const enemyConfig = require('../configs/enemyConfig');
module.exports = class {
    constructor() {
        this.enemyPrefab = null;
        //
        this.enemyMap = {};
        this.enemyPool = new cc.NodePool();
        this.enemyCurLevel = 0;
        //
        this.curEnemyCount = 0;
        this.enemyHpAdd = 1;
        //
        this.init();
    }

    init() {
        //
        this.enemyLayer = cc.find('Canvas/layerGame/gameLayerEnemy');
    }

    loadEnemyRes() {
        ICPC.addOneLoad();
        cc.loader.loadRes(enemyConfig.enemyPrefabPath, cc.Prefab, (error, resource) => {
            if (error) {
                throw error;
            }
            if (!(resource instanceof cc.Prefab)) {
                console.error('#25 Prefab error', enemyConfig.enemyPrefabPath);
                return;
            }
            this.enemyPrefab = resource;
            ICPC.emit('loadEnemyResEnd');
            ICPC.oneLoadOver();
        });
    }

    //私用
    newEnemy() {
        if (this.enemyPool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
            return this.enemyPool.get();
        } else { // 如果没有空闲对象，也就是对象池中备用对象不够时，我们就用 cc.instantiate 重新创建
            return cc.instantiate(this.enemyPrefab);
        }
    }

    //私用
    deleteEnemy(enemyNode, isOver) {
        this.enemyPool.put(enemyNode);
        //
        if (isOver) return;
        //
        ICPC.mainJS.scheduleOnce(this.continueEnemy.bind(this), 0)
        // this.continueEnemy();
    }

    setEnemyLevel(level) {
        this.enemyCurLevel = level;
    }

    clearAll() {
        for (let id in this.enemyMap) {
            this.killEnemy(id, true);
        }
        this.enemyCurLevel = 0;
        this.enemyHpAdd = 1;
    }

    enemyLevelUp() {
        //
        this.enemyCurLevel++;
        //已经打过最后一轮
        if (this.enemyCurLevel >= enemyConfig.enemyLevels.length) {
            this.enemyCurLevel--;
            this.enemyHpAdd++;
            ICPC.effectManager.addEffect({
                effectName: 'message1',
                effectInfo: `挑战升级 敌方血量 ×${this.enemyHpAdd * 100}%`
            }, cc.v2(0, 0));
        } else {
            ICPC.effectManager.addEffect({effectName: 'message1', effectInfo: `关卡升级`}, cc.v2(0, 0));
        }
    }

    getEnemyCurConfig() {
        if (enemyConfig.enemyLevels[this.enemyCurLevel]) {
            return JSON.parse(JSON.stringify(enemyConfig.enemyLevels[this.enemyCurLevel]));
        }
        throw '敌人等级错误' + this.enemyCurLevel;
    }

    startEnemy() {
        this.curEnemyCount = 0;
        this.continueEnemy();
    }

    onIsEnemySuccess() {
        const conf = this.getEnemyCurConfig();
        if (Object.keys(this.enemyMap).length == 0) {
            ICPC.gameDataManager.onEnemySuccess();
        }
        //
    }

    //继续出敌人
    continueEnemy() {
        const conf = this.getEnemyCurConfig();
        //数量已经出完
        if (this.curEnemyCount >= conf.num) {
            this.onIsEnemySuccess();
        } else {
            //
            let enemyEd = conf.oneNumMin + Math.floor(Math.random() * (conf.oneNumMax - conf.oneNumMin));
            const FullNumMax = conf.FullNumMax;//同屏最多多少少
            //同屏不允许超过FullNumMax个
            enemyEd = Math.min(enemyEd, FullNumMax - Object.keys(this.enemyMap).length);
            for (let i = 0; i < enemyEd; i++) {
                //出
                if (this.curEnemyCount++ < conf.num) {
                    //
                    let info = JSON.parse(JSON.stringify(conf));
                    //随机横向速度
                    info.xv = conf.xvMin + Math.random() * (conf.xvMax - conf.xvMin);
                    info.xv = Math.floor(info.xv);
                    info.hp = conf.hpMin + Math.random() * (conf.hpMax - conf.hpMin);
                    info.hp = Math.floor(info.hp);
                    //无限关加成
                    info.hp *= this.enemyHpAdd;
                    //尺寸缩放
                    info.size = conf.sizeMin + Math.random() * (conf.sizeMax - conf.sizeMin);
                    info.size = info.size / 100;
                    if (Math.random() > 0.5) {
                        info.xv *= -1;
                    }
                    this.addEnemy(info);
                } else {//出不动了
                    break;
                }
            }
        }
    }

    getEnemy(id) {
        return this.enemyMap[id];
    }

    addEnemy(enemyInfo) {
        enemyInfo = JSON.parse(JSON.stringify(enemyInfo));
        //
        const id = ICPC.randId();
        let enemyNode = this.newEnemy();
        this.enemyMap[id] = {
            m_node: enemyNode,
            m_info: enemyInfo,
        };
        this.enemyLayer.addChild(enemyNode);
        let posX = Math.random() * ICPC.layerGame.width - ICPC.layerGame.width / 2;
        enemyNode.setPosition(posX, ICPC.layerGame.height / 2 - 100);
        enemyNode.getComponent('enemy').initEnemy(id, enemyInfo);
        //通知外部
        ICPC.emit('addEnemy', id);
    }

    killEnemy(id, isClear = false) {
        //
        let enemy = this.enemyMap[id];
        if (enemy) {
            //非清理
            if(!isClear){
                ICPC.soundManager.playBoom();
                ICPC.effectManager.addEffect({effectName:'boom1'}, enemy.m_node.getPosition());
            }
            delete this.enemyMap[id];
            this.deleteEnemy(enemy.m_node, isClear);
        } else {
            console.error('敌机无效');
        }
    }

    onBoomForId(id) {
        let enemy = this.getEnemy(id);
        if (enemy == null) {
            //
            // console.warn('#154 敌机已经被同一帧的其他子弹消灭');
            return;
        }
        const hurt = ICPC.gameDataManager.getBulletHurt();
        //
        enemy.m_info.hp -= hurt;
        //分数按打掉的血量 不能为负血量加分
        if (enemy.m_info.hp < 0) {
            //成绩记录
            ICPC.gameDataManager.addScore(hurt + enemy.m_info.hp);
        } else {
            //成绩记录
            ICPC.gameDataManager.addScore(hurt);
        }
        enemy.m_node.getComponent('enemy').setHp(enemy.m_info.hp);
        //
        if (enemy.m_info.hp <= 0) {
            this.killEnemy(id);
        }
    }
}